using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace AlphaWindow
{
	partial class AlphaButton : Button, ISkinnableControl
	{
		private Pen countourPen;
		private Brush fillBrush;
		private Brush activeFillBrush;
		private Brush textBrush;
		private Brush pressedFill;

		internal StringFormat pStringFormater;

		private bool CursorIsOver = false;
		private bool Pressed;

		private bool _pFilledContour = true;
		private bool _pFilled = true;
		private StringAlignment _pHorzAlign = StringAlignment.Center;
		private StringAlignment _pVerAlign = StringAlignment.Center;
		private bool _AlphaRequired = true;

		//==================================================================================================================
		public AlphaButton()
		{
			InitializeComponent();

			pStringFormater = new StringFormat();
			pStringFormater.Trimming = StringTrimming.EllipsisCharacter;
			countourPen = new Pen(SkinColors.ButtonContourColor, 1);
			fillBrush = new SolidBrush(SkinColors.ButtonFillColor);
			activeFillBrush = new SolidBrush(SkinColors.ButtonActFillColor);
			textBrush = new SolidBrush(SkinColors.ButtonTextColor);
			pressedFill = new SolidBrush(SkinColors.ButtonPressedColor);
		}

		//==================================================================================================================
		public AlphaButton(IContainer container)
		{
			container.Add(this);
			InitializeComponent();

			if (!DesignMode)
			{
				SetStyle(ControlStyles.UserPaint, true);
				SetStyle(ControlStyles.AllPaintingInWmPaint, true);
				SetStyle(ControlStyles.Opaque, true);
				SetStyle(ControlStyles.Selectable, true);
				SetStyle(ControlStyles.SupportsTransparentBackColor, true);
			}

			pStringFormater = new StringFormat();
			pStringFormater.Trimming = StringTrimming.EllipsisCharacter;
			countourPen = new Pen(SkinColors.ButtonContourColor, 1);
			fillBrush = new SolidBrush(SkinColors.ButtonFillColor);
			activeFillBrush = new SolidBrush(SkinColors.ButtonActFillColor);
			textBrush = new SolidBrush(SkinColors.ButtonTextColor);
			pressedFill = new SolidBrush(SkinColors.ButtonPressedColor);
		}

		public bool pFilledContour
		{
			get { return _pFilledContour; }
			set { _pFilledContour = value; }
		}

		public bool pFilled
		{
			get { return _pFilled; }
			set { _pFilled = value; }
		}

		public StringAlignment pHorzAlign
		{
			get { return _pHorzAlign; }
			set { _pHorzAlign = value; }
		}

		public StringAlignment pVerbAlign
		{
			get { return _pVerAlign; }
			set { _pVerAlign = value; }
		}

		public bool AlphaRequired
		{
			get { return _AlphaRequired; }
			set { _AlphaRequired = value; }
		}

		internal Pen CountourPen
		{
			get { return countourPen; }
			set { countourPen = value; }
		}

		internal Brush FillBrush
		{
			get { return fillBrush; }
			set { fillBrush = value; }
		}

		internal Brush ActiveFillBrush
		{
			get { return activeFillBrush; }
			set { activeFillBrush = value; }
		}

		internal Brush TextBrush
		{
			get { return textBrush; }
			set { textBrush = value; }
		}

		internal Brush PressedFill
		{
			get { return pressedFill; }
			set { pressedFill = value; }
		}

		public void RedrawControl(Graphics GFX)
		{
			if (!Visible)
				return;


			// ---------------- fills
			Rectangle bases = new Rectangle(Left + 0, Top + 0, Width - 1, Height - 1);
			using (GraphicsPath gg = SkinHelper.GetGraphicsPath(this, false, false))
			{
				if (CursorIsOver)
				{
					if (!Pressed)
						GFX.FillPath(activeFillBrush, gg);
					else
						GFX.FillPath(pressedFill, gg);

					GFX.CompositingMode = CompositingMode.SourceOver;
					GFX.SmoothingMode = SmoothingMode.HighQuality;
		
					GFX.DrawPath(countourPen, gg);

					GFX.CompositingMode = CompositingMode.SourceCopy;
					GFX.SmoothingMode = SmoothingMode.None;

				}
				else
				{
					if (pFilled)
					{
						GFX.FillPath(fillBrush, gg);

						if (pFilledContour)
						{
							GFX.CompositingMode = CompositingMode.SourceOver;
							GFX.SmoothingMode = SmoothingMode.HighQuality;

							GFX.DrawPath(countourPen, gg);

							GFX.CompositingMode = CompositingMode.SourceCopy;
							GFX.SmoothingMode = SmoothingMode.None;
						}
					}
					else
					{
						if (pFilledContour)
						{
							GFX.CompositingMode = CompositingMode.SourceOver;
							GFX.SmoothingMode = SmoothingMode.HighQuality;

							GFX.DrawPath(countourPen, gg);

							GFX.CompositingMode = CompositingMode.SourceCopy;
							GFX.SmoothingMode = SmoothingMode.None;
						}
					}
				}
			}

			if (Image == null)
			{
				GFX.CompositingMode = CompositingMode.SourceOver;
				GFX.SmoothingMode = SmoothingMode.HighQuality;
				
				pStringFormater.LineAlignment = pVerbAlign;
				pStringFormater.Alignment = pHorzAlign;
				GFX.DrawString(Text, Font, textBrush, bases, pStringFormater);

				GFX.CompositingMode = CompositingMode.SourceCopy;
				GFX.SmoothingMode = SmoothingMode.None;
			}
			else
			{
				GFX.CompositingMode = CompositingMode.SourceOver;

				if (pFilledContour)
					GFX.DrawImageUnscaled(Image, (int)Math.Ceiling(Left + (bases.Width - Image.Width) / 2d), (int)Math.Ceiling(Top + (bases.Height - Image.Height) / 2d));
				else
					GFX.DrawImageUnscaled(Image, (int)Math.Ceiling(Left + (bases.Width - Image.Width) / 2d) + 1, (int)Math.Ceiling(Top + (bases.Height - Image.Height) / 2d) + 1);

				GFX.CompositingMode = CompositingMode.SourceCopy;
			}

		}

		private void RequestRedraw()
		{
			if (Parent is ISkinnableForm)
				((ISkinnableForm)Parent).RedrawRequested();
			else if (Parent is ISkinnableControl && Parent.Parent is ISkinnableForm)
				((ISkinnableForm)Parent.Parent).RedrawRequested();
		}

		private void AlphaButton_MouseEnter(object sender, EventArgs e)
		{
			CursorIsOver = true;
			RequestRedraw();
		}

		private void AlphaButton_MouseLeave(object sender, EventArgs e)
		{
			Pressed = false;
			CursorIsOver = false;
			RequestRedraw();
		}

		private void AlphaButton_MouseDown(object sender, MouseEventArgs e)
		{
			Pressed = true;
			RequestRedraw();
		}

		private void AlphaButton_MouseUp(object sender, MouseEventArgs e)
		{
			Pressed = false;
			RequestRedraw();
		}

		private void AlphaButton_KeyUp(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Tab)
			{
				RequestRedraw();
			}
		}

	}
}
